﻿using System;
using System.Diagnostics;
using System.Linq;
using WaitLess.App.Services.Interfaces;
using WaitLess.Business.Data.Model.Foursquare.CheckinRequest;
using WaitLess.Business.Model;
using WaitLess.Business.Repositories.Interfaces;
using WaitLess.Business.Services.Interfaces;

namespace WaitLess.App.ViewModels
{
    public class DetailsViewModel : ViewModelBase
    {
        private readonly IDataCache _dataCache;
        private readonly IMunicipalOfficeLoader _municipalOfficeLoader;
        private readonly ICheckinRepository _checkinRepository;
        private readonly IGps _gps;

        public bool CanCheckIn { get; private set; }
        private string VenueId { get; set; }
        private string Longitude { get; set; }
        private string Latitude { get; set; }

        private string _municipalOfficeId;
        public string MunicipalOfficeId 
        {
            get { return _municipalOfficeId; }
            set { SetProperty(ref _municipalOfficeId, value, "MunicipalOfficeId"); }
        }

        private string _title;
        public string Title
        {
            get { return _title; }
            set { SetProperty(ref _title, value, "Title"); }
        }

        private string _address;
        public string Address
        {
            get { return _address; }
            set { SetProperty(ref _address, value, "Address"); }
        }

        private string _hereNowCount;
        public string HereNowCount
        {
            get { return _hereNowCount; }
            set { SetProperty(ref _hereNowCount, value, "HereNowCount"); }
        }

        public DetailsViewModel(IDataCache dataCache, IMunicipalOfficeLoader municipalOfficeLoader,
            ICheckinRepository checkinRepository, IGps gps)
        {
            if (dataCache == null) throw new ArgumentNullException("dataCache");
            if (municipalOfficeLoader == null) throw new ArgumentNullException("municipalOfficeLoader");
            if (checkinRepository == null) throw new ArgumentNullException("checkinRepository");
            if (gps == null) throw new ArgumentNullException("gps");

            _dataCache = dataCache;
            _municipalOfficeLoader = municipalOfficeLoader;
            _checkinRepository = checkinRepository;
            _gps = gps;
        }

        public override void LoadData()
        {
            HereNowCount = "...";
            CanCheckIn = true;

            _dataCache.Load(() => UpdateUI(LoadMunicipalOffice));
        }

        private void LoadMunicipalOffice()
        {
            var municipalOffice = _dataCache.Districshuizen
                .Union(_dataCache.Stadskantoren)
                .SingleOrDefault(o => o.Id == _municipalOfficeId);

            Title = municipalOffice.Name;
            Address = string.Format("{0} {1}, {2} {3}", municipalOffice.Street, municipalOffice.HouseNumber, municipalOffice.PostalCode, municipalOffice.District);
            Longitude = municipalOffice.Longitude;
            Latitude = municipalOffice.Latitude;

            LoadHereNowCount();
        }

        private void LoadHereNowCount()
        {
            var currentCheckedInRequest = new CurrentCheckedInRequest
            {
                AccessToken = _dataCache.FoursquareAccessToken,
                MunicipalOfficeName = Title,
                ReceiveResult = UpdateHereNowCount,
                ReceiveVenueId = UpdateVenueId
            };

            _municipalOfficeLoader.GetCurrentCheckedInCount(currentCheckedInRequest);
        }

        private void UpdateHereNowCount(int? count)
        {
            UpdateUI(() => 
            {
                if (count.HasValue)
                    HereNowCount = count.ToString();
                else
                    HereNowCount = "?";

                IsDataLoaded = true;
            });
        }

        private void UpdateVenueId(string venueId)
        {
            VenueId = venueId;
            CanCheckIn = true;
        }

        public void CheckIn()
        {
            UpdateUI(() => { IsDataLoaded = false; });
            CanCheckIn = false;

            var request = new Request
            {
                AccessToken = _dataCache.FoursquareAccessToken,
                VenueId = VenueId,
                Latitude = Latitude,
                Longitude = Longitude
            };

            _checkinRepository.Create(request, () =>  
            {
                LoadHereNowCount();
            });
        }
    }
}